aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/[username]/settings/_account.svelte
blob: 8b9eeec578804f26e15f556c6d97917896cb42f4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<script>
	import { tick } from 'svelte';
	import {
		user,
		colorTheme,
		rates,
		tempProfileFiles,
		avatarUpload,
		bannerUpload
	} from '$lib/store';
	import { Icon, Toggle, LocaleSelector } from '$comp';
	import { t } from '$lib/translations';
	import { upload } from '$lib/upload';

	let selectedTheme = 1;
	let revealPassword = false;
	let password;
	let profileFile;
	let select = (type) => files[type].el.click();

	$: profile = files.profile.src;
	$: banner = files.banner.src;
	$: $tempProfileFiles = { profile: files.profile.src, banner: files.banner.src };

	let colorThemes = [
		{ theme: 1, color1: 'from-[#F5F7FA]', color2: 'to-[#C3CFE2]' },
		{ theme: 2, color1: 'from-[#FDFCFB]', color2: 'to-[#E2D1C3]' },
		{ theme: 3, color1: 'from-[#E6E9F0]', color2: 'to-[#EEF1F5]' },
		{ theme: 4, color1: 'from-[#D5D4D0]', color2: 'to-[#EEEEEC]' },
		{ theme: 5, color1: 'from-[#F3E7E9]', color2: 'to-[#E3EEFF]' },
		{ theme: 6, color1: 'from-[#F5F7FA]', color2: 'via-[#EAF2FF] to-[#DEDFFF]' }
	];

	let handleThemeClick = (colors) => {
		selectedTheme = colors.theme;
		$colorTheme = colors.color1 + ' ' + colors.color2;
	};

	let percent;
	let progress = async (event) => {
		percent = Math.round((event.loaded / event.total) * 100);
	};

	let files = { profile: {}, banner: {} };
	let handleFile = async ({ target }, type) => {
		let file = target.files[0];
		var reader = new FileReader();
		reader.onload = async (e) => {
			files[type].src = e.target.result;
		};
		reader.readAsDataURL(file);

		files[type].filename = file.name;
		if (type === 'profile') {
			$avatarUpload = { file, type, progress };
		} else if (type === 'banner') {
			$bannerUpload = { file, type, progress };
		}
	};

	$: $user.password = $user.confirm = password;
</script>

<div>
	<label for="language" class="font-bold block mb-1">{$t('user.settings.locale')}</label>
	<LocaleSelector style="select-styles block py-3 w-full" />
</div>

<!-- TODO
<div>
	<label for="email" class="font-bold mb-1 block">{$t('user.settings.email')}</label>
	<input type="email" name="email" bind:value={$user.email} />
</div> -->

<!-- TODO fix breaking changes when user updates this field -->
<div>
	<label for="username" class="font-bold mb-1 block">{$t('user.settings.username')}</label>
	<input disabled type="text" name="username" bind:value={$user.username} />
</div>

<div class="relative">
	<label for="password" class="block font-bold block mb-1">{$t('user.settings.newPassword')}</label>
	{#if revealPassword}
		<input type="text" bind:value={password} />
	{:else}
		<input type="password" bind:value={password} />
	{/if}
	<button
		type="button"
		on:click={() => (revealPassword = !revealPassword)}
		class="absolute right-5 top-11"
	>
		<Icon icon={revealPassword ? 'eye' : 'eye-off'} />
	</button>
</div>

<div>
	<label for="address" class="font-bold mb-1 block">{$t('user.settings.businessAddress')}</label>
	<input type="text" name="address" bind:value={$user.address} />
</div>

<!-- TODO -->
<!-- <div> -->
<!-- 	<div class="flex justify-between items-center"> -->
<!-- 		<span class="font-bold">{$t('user.settings.emailNotifications')}</span> -->
<!-- 		<Toggle id="email-notify" /> -->
<!-- 	</div> -->
<!-- 	<p class="text-secondary mt-1 w-9/12"> -->
<!-- 		{$t('user.settings.emailNotificationsDescription')} -->
<!-- 	</p> -->
<!-- </div> -->
<!--  -->
<!-- <div> -->
<!-- 	<div class="flex justify-between items-center"> -->
<!-- 		<span class="font-bold">{$t('user.settings.smsNotifications')}</span> -->
<!-- 		<Toggle id="sms-notify" /> -->
<!-- 	</div> -->
<!-- 	<p class="text-secondary mt-1 w-9/12"> -->
<!-- 		{$t('user.settings.smsNotificationsDescription')} -->
<!-- 	</p> -->
<!-- </div> -->

<div>
	<span class="font-bold">{$t('user.settings.profileImage')}</span>
	<div class="flex">
		{#if profile}
			<div class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto">
				<img
					src={profile}
					class="absolute w-full h-full object-cover object-center visible overflow-hidden"
				/>
			</div>
		{:else if $user.profile}
			<div class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto">
				<img
					src={`/api/public/${$user.username}-profile.png`}
					class="absolute w-full h-full object-cover object-center visible overflow-hidden"
				/>
			</div>
		{:else}
			<div
				class="rounded-full border-4 border-white p-4 bg-gradient-to-r {$colorTheme} w-24 my-auto"
			>
				<Icon icon="logo-symbol-white" style="mx-auto" />
			</div>
		{/if}
		<div class="ml-2 p-2">
			<!-- found missing translation -->
			<button
				type="button"
				class="border rounded-2xl font-bold w-24 text-center px-0 py-2 hover:bg-primary"
				on:click={() => select('profile')}>Select</button
			>
			<input
				type="file"
				class="hidden"
				bind:this={files.profile.el}
				on:change={(e) => handleFile(e, 'profile')}
			/>
			{#if files.profile.filename}
				<div class="mt-2 text-sm">{files.profile.filename}</div>
			{/if}
		</div>
	</div>
</div>

<div>
	<div class="flex justify-between items-center">
		<span class="font-bold">{$t('user.settings.bannerImage')}</span>
	</div>
	<!-- found missing translation -->
	<p class="text-secondary mb-4">Recommended size: 1920x175px</p>
	{#if banner}
		<img src={banner} class="w-full object-cover object-center visible overflow-hidden h-48 mb-4" />
	{:else if $user.banner}
		<img
			src={`/api/public/${$user.username}-banner.png`}
			class="w-full object-cover object-center visible overflow-hidden h-48 mb-4"
		/>
	{:else}
		<div
			class="bg-gradient-to-r {$colorTheme} w-full h-48 mb-4 cursor-pointer"
			on:click={() => select('banner')}
		/>
	{/if}

	<!-- found missing translation -->
	<button
		type="button"
		class="border rounded-2xl font-bold w-24 text-center px-0 py-2 hover:bg-primary"
		on:click={() => select('banner')}>Select</button
	>
	<input
		type="file"
		class="hidden"
		bind:this={files.banner.el}
		on:change={(e) => handleFile(e, 'banner')}
	/>
	{#if files.banner.filename}
		<div class="mt-2 text-sm">{files.banner.filename}</div>
	{/if}
</div>

<div>
	<span class="font-bold mb-1 block">{$t('user.settings.theme')}</span>
	<p class="text-secondary mb-1">{$t('user.settings.themeDescription')}</p>
	{#each colorThemes as colors}
		<button
			type="button"
			class="mr-2 w-10 h-10 bg-gradient-to-r {colors.color1} {colors.color2} rounded-xl border-2 {selectedTheme ===
			colors.theme
				? 'border-black'
				: ''}"
			on:click={() => handleThemeClick(colors)}
		/>
	{/each}
</div>